﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SiGeSIB.GUI.Properties;
using SiGeSIB.Services;
using SiGeSIB.GUI.Common;
using SiGeSIB.Data.Security;
using SiGeSIB.Data.Common;
using SiGeSIB;

namespace GUI.Security
{
	
#if DESIGN
	public partial class FEditPermission : FormRedirector.FEditPermission
#else
	public partial class FEditPermission : FGenericEditor<EPermissions>
#endif
	{
		#region ColumnsNames
		private const string DT_ID = "Id";
		private const string DT_STATUSIMAGE = "Status";
		private const string DT_DESCRIPTION = "Description";
		private const string DT_STATUSCOMBO = "StatusPermission";
		#endregion

        #region Constructor
        public FEditPermission(int id)
			: base(EFormState.View, id)
        {
            InitializeComponent();

			_CurrentId = id;
			_IdleMessage = "Edite as permissões do usuário.";

			dataGridPermissions.AutoGenerateColumns = false;
			this.Text = "Edição de permissões de usuário";

			dataGridPermissions.EditMode = DataGridViewEditMode.EditOnEnter;
			dataGridPermissions.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridPermissions_EditingControlShowing);
			FieldsToLock = new List<object>() { dataGridPermissions };
        }
        #endregion

		#region Properties
		protected override bool HasEditPermission
		{
			get
			{
				return
					Manager.Instance.LoggedUser.IsAdmin
					||
					(
						Manager.Instance.LoggedUser.Permissions
						&
						EPermissions.ManagePermissions
					) != EPermissions.None;
			}
		}
		#endregion

		#region Attributes
		private bool _IgnoreValueChanged;
		private Image _AllowedImage = Resources.button_green1;
		private Image _DeniedImage = Resources.button_red;
		private DataTable _DtPermissions;
		private int _CurrentId;
		#endregion

		#region Methods
		#region General
		private void _RefreshUIState()
		{
			bool isEnabled = !_Controller.IsBusy;
			dataGridPermissions.ReadOnly = !isEnabled;
		}
		#endregion

		#region Loading
		private void _CreateDataTable()
		{
			if (_DtPermissions == null)
			{
				_DtPermissions = new DataTable();
				_DtPermissions.Columns.Add(DT_STATUSIMAGE, typeof(Image));
				_DtPermissions.Columns.Add(DT_DESCRIPTION, typeof(string));
				_DtPermissions.Columns.Add(DT_STATUSCOMBO, typeof(string));
				_DtPermissions.Columns.Add(DT_ID, typeof(int));
			}
			else
				_DtPermissions.Clear();
		}
		#endregion

		#region Commit
		protected override EPermissions _BuildEntity()
		{
			EPermissions permissions = EPermissions.None;

			// Ele olha para o valor da combo na grid porque a alteração pode não estar comitada ainda
			// Depois pega o id no DataRow porque não existe uma coluna da grid que guarde o valor do Enum
			foreach (DataGridViewRow dgvr in dataGridPermissions.Rows)
				if ((dgvr.Cells[DT_STATUSCOMBO].EditedFormattedValue as string).Equals("Permitido"))
					permissions = permissions | (EPermissions)((dgvr.DataBoundItem as DataRowView).Row[DT_ID]);

			return permissions;
		}
		#endregion

		#region Event Handlers
		private void dataGridPermissions_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
		{
			var combo = e.Control as DataGridViewComboBoxEditingControl;

			combo.SelectedValueChanged -= new EventHandler(combo_SelectedValueChanged);
			combo.SelectedValueChanged += new EventHandler(combo_SelectedValueChanged);
			combo.DropDown -= new EventHandler(combo_DropDown);
			combo.DropDown += new EventHandler(combo_DropDown);
		}

		private void combo_DropDown(object sender, EventArgs e)
		{
			((ComboBox)sender).BackColor = Color.White;
		}

		private void combo_SelectedValueChanged(object sender, EventArgs e)
		{
			if (!_IgnoreValueChanged)
			{
				_IgnoreValueChanged = true;
				DataGridViewRow dgvr = dataGridPermissions.CurrentRow;
				string status = dgvr.Cells[DT_STATUSCOMBO].EditedFormattedValue as string;
				dgvr.Cells[DT_STATUSIMAGE].Value = status == "Permitido" ? _AllowedImage : _DeniedImage;
				_IgnoreValueChanged = false;
			}
		}
		#endregion

		#region Overridens
		protected override EPermissions _LoadEntity(int id)
		{
			ISecurityServicesProvider secProv = Manager.Instance.ServicesProvider.CreateSecurityServicesProvider();
			return secProv.GetUserPermissions(id);
		}

		protected override void _FillEntity(EPermissions entity)
		{
			_CreateDataTable();

			foreach (EPermissions p in Enum.GetValues(typeof(EPermissions)))
			{
				bool hasPermission = (p & entity) != 0;

				if (p != EPermissions.None)
					_DtPermissions.Rows.Add(hasPermission ? _AllowedImage : _DeniedImage, p.GetDescription(), hasPermission ? "Permitido" : "Negado", (int)p);
			}
			dataGridPermissions.DataSource = null;
			dataGridPermissions.DataSource = _DtPermissions;
		}

		protected override ExceptionsContainer _ValidateEntity(EPermissions entity)
		{
			return null;
		}

		protected override int _SaveEntity(EPermissions entity)
		{
			ISecurityServicesProvider secProv = Manager.Instance.ServicesProvider.CreateSecurityServicesProvider();
			secProv.SaveUserPermissions(_CurrentId, entity);

			return _CurrentId;
		} 
		#endregion
		#endregion
	}
}
